﻿using GrayParrot.Core.Data;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace GrayParrot.Data.ADONET
{
    public class UnitOfWork : IUnitOfWork
    {
        private IDbTransaction _transaction;
        private readonly Action<UnitOfWork> _rolledBack;
        private readonly Action<UnitOfWork> _committed;

        public UnitOfWork(IDbTransaction transaction, Action<UnitOfWork> rolledBack, Action<UnitOfWork> committed)
        {
            Transaction = transaction;
            _transaction = transaction;
            _rolledBack = rolledBack;
            _committed = committed;
        }

        public IDbTransaction Transaction { get; private set; }

        public void Dispose()
        {
            if (_transaction == null)
                return;

            try
            {
                _transaction.Rollback();
                _rolledBack(this);
            }
            finally
            {
                _transaction.Dispose();
                _transaction = null;
            }
        }

        public void SaveChanges()
        {
            if (_transaction == null)
                throw new InvalidOperationException("This unit of work has already been saved or undone.");

            try
            {
                _transaction.Commit();
                _committed(this);
            }
            catch (Exception ex)
            {
                GrayParrot.Logging.Logger.For<UnitOfWork>().Error(ex);
            }
            finally
            {
                _transaction.Dispose();
                _transaction = null;
            }
        }
    }
}
